package top.jfunc.common.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 文件工具
 * @author 熊诗言
 */
public class FileUtil {
    private static final Logger logger = LoggerFactory.getLogger(FileUtil.class);
    private FileUtil(){}

    /**
     * Java文件操作 获取文件扩展名
     * @param filename 文件名
     * @return 扩展名
     */
    public static String getExtensionName(String filename) {
        if ((filename != null) && (filename.length() > 0)) {
            int dot = filename.lastIndexOf('.');
            if ((dot >-1) && (dot < (filename.length() - 1))) {
                return filename.substring(dot + 1);
            }
        }
        return filename;
    }

    /**
     * Java文件操作 获取不带扩展名的文件名
     * @param filename 文件名
     * @return 不带扩展名的文件名
     */
    public static String getFileNameNoEx(String filename) {
        if ((filename != null) && (filename.length() > 0)) {
            int dot = filename.lastIndexOf('.');
            if ((dot >-1) && (dot < (filename.length()))) {
                return filename.substring(0, dot);
            }
        }
        return filename;
    }

    public static boolean makeSureExistDir(String fileDir){
        File file = new File(fileDir);
        return makeSureExistDir(file);
    }

    public static boolean makeSureExistDir(File dirFile){
        if(!dirFile.exists()){
            return dirFile.mkdirs();
        }
        return true;
    }

    public static boolean makeSureExistFile(String fileName) throws IOException {
        File file = new File(fileName);
        return makeSureExistFile(file);
    }

    public static boolean makeSureExistFile(File file) throws IOException {
        if(file.exists()){
            return true;
        }
        //先确保父目录存在
        File parentFile = file.getParentFile();
        makeSureExistDir(parentFile);

        return file.createNewFile();
    }

    /**
     * 连接目录名+文件名，自动处理分隔符
     * @param dir 目录名
     * @param fileName  文件名，可以带分隔符
     * @return 连接后的文件名
     */
    public static String concat(String dir , String fileName){
        if(StrUtil.isEmpty(fileName)){
            throw new IllegalArgumentException("fileName 不允许为空");
        }
        if(StrUtil.isEmpty(dir)){
            return fileName;
        }
        if(endsWithSplash(dir) && startsWithSplash(fileName)){
            return dir + fileName.substring(1);
        }
        if(!endsWithSplash(dir) && !startsWithSplash(fileName)){
            return dir + File.separator + fileName;
        }
        return dir + fileName;
    }

    private static boolean endsWithSplash(String name){
        //以/或者\结尾
        return name.endsWith(StrUtil.SLASH) || name.endsWith(StrUtil.BACKSLASH);
    }
    private static boolean startsWithSplash(String name){
        //以/或者\开头
        return name.startsWith(StrUtil.SLASH) || name.startsWith(StrUtil.BACKSLASH);
    }


    /**
     * 循环删除一个文件夹的所有文件
     */
    public static boolean deleteRecursively(File root) {
        if (root != null && root.exists()) {
            if (root.isDirectory()) {
                File[] children = root.listFiles();
                if (children != null) {
                    for (File child : children) {
                        deleteRecursively(child);
                    }
                }
            }
            return root.delete();
        }
        return false;
    }


    /**
     * 删除一个文件
     */
    public static void deleteFile(String fileName) {
        deleteFile(new File(fileName));
    }
    public static void deleteFile(File file) {
        if (file.exists()) {
            file.delete();
        }
    }


    public static void writeFileContent(File file, byte[] data, boolean append) {
        if (!file.exists()) {
            file.getParentFile().mkdirs();
        }

        try (FileOutputStream fos = new FileOutputStream(file, append)){
            fos.write(data);
            fos.flush();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
    }

    public static byte[] readFileContent(File file) {
        long filelength = file.length();
        byte[] filecontent = new byte[(int) filelength];

        try (FileInputStream in = new FileInputStream(file)){
            in.read(filecontent);
            return filecontent;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return null;
        }
    }
}
